# -*- coding: utf-8 -*-
"""
患者评估报告PDF生成器 - 三列表格格式
包含 HAMD-17、HAMA-14、YMRS 三个量表
结果列显示具体得分对应的详细描述
"""
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer, PageBreak
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.lib.enums import TA_CENTER, TA_LEFT
import datetime
import os
import re

# HAMD-17 抑郁量表完整题目
HAMD_QUESTIONS = [
    {'num': 1, 'title': '抑郁情绪', 'description': '0.无 1.只有问到时才诉述 2.在谈话中自发表达 3.不用言语也可从表情、姿势、声音中流露出这种情绪 4.病人的自发言语和非言语表达（表情、动作），几乎完全表现为这种情绪'},
    {'num': 2, 'title': '罪恶感', 'description': '0.无 1.自责，觉得自己已连累他人 2.认为自己犯了罪，或反复思考以往的过失和错误 3.现在的疾病是一种惩罚，有罪恶妄想 4.听到谴责或控告自己的声音，和/或有威胁性的幻觉'},
    {'num': 3, 'title': '自杀', 'description': '0.无 1.觉得活着没有意义 2.希望自己已经死去，或常想到与死有关的事 3.有自杀的观念或姿态 4.有自杀行为'},
    {'num': 4, 'title': '入睡困难', 'description': '0.无入睡困难 1.偶有入睡困难，即上床后半小时以上方能入睡 2.每夜均有入睡困难'},
    {'num': 5, 'title': '睡眠不深', 'description': '0.无 1.睡眠浅、易醒或整夜睡眠不安 2.夜间惊醒，离床或在房间内走动（排除生理需要）'},
    {'num': 6, 'title': '早醒', 'description': '0.无 1.早醒，但能再入睡 2.醒后不能再入睡'},
    {'num': 7, 'title': '工作和兴趣', 'description': '0.无 1.对以往的爱好稍感兴趣减退 2.对工作、活动或业余爱好明显缺乏兴趣 3.对工作、活动或业余爱好已经失去兴趣 4.已停止工作，不参加任何活动'},
    {'num': 8, 'title': '迟滞', 'description': '0.思维和言语正常，活动并不缓慢 1.精神检查时轻度迟缓 2.精神检查时明显迟缓 3.精神检查困难 4.完全木僵'},
    {'num': 9, 'title': '激越', 'description': '0.无 1.坐立不安 2.玩弄手指、头发等 3.不停地动，不能静坐 4.搓手、咬指甲、扯头发、咬嘴唇'},
    {'num': 10, 'title': '精神性焦虑', 'description': '0.无 1.轻度紧张和易激惹 2.为小事担心 3.明显的焦虑，表现在面部和言谈中 4.不问也诉说有恐惧感'},
    {'num': 11, 'title': '躯体性焦虑', 'description': '0.无 1.轻度 2.中度，有明确的一项或多项症状 3.重度，上述症状严重 4.极重度，上述症状严重且已妨碍其它活动'},
    {'num': 12, 'title': '胃肠道症状', 'description': '0.无 1.食欲减退，但不需他人鼓励即可进食 2.进食需他人催促，或需要用通便药或助消化药'},
    {'num': 13, 'title': '全身症状', 'description': '0.无 1.肢体、背部或头部沉重感，背痛、头痛、肌肉痛，乏力，失去精力 2.任何上述症状明显者'},
    {'num': 14, 'title': '性症状', 'description': '0.无症状 1.轻度：性欲减退 2.严重：性欲明显减退'},
    {'num': 15, 'title': '疑病', 'description': '0.无 1.对身体过分关注 2.反复考虑健康问题 3.有疑病妄想 4.躯体疾病的幻觉'},
    {'num': 16, 'title': '体重减轻', 'description': '0.无体重减轻 1.可能有体重减轻 2.明显的体重减轻（一周减轻0.5公斤以上）'},
    {'num': 17, 'title': '自知力', 'description': '0.认识到自己有抑郁症或有病，需要治疗 1.认识到有病，但归咎于饮食、气候、工作过度等 2.完全否认有病'}
]

# HAMA-14 焦虑量表完整题目
HAMA_QUESTIONS = [
    {'num': 1, 'title': '焦虑心境', 'description': '0.无 1.轻度 2.中度，患者描述较明确 3.重度，严重影响患者生活 4.极重度，不可克制'},
    {'num': 2, 'title': '紧张', 'description': '0.无 1.轻度 2.中度，患者明显表现出紧张 3.重度，患者面部及躯体表现紧张 4.极重度，紧张达极点'},
    {'num': 3, 'title': '害怕', 'description': '0.无 1.轻度 2.中度，害怕明显 3.重度，严重影响患者生活 4.极重度，不可控制的害怕'},
    {'num': 4, 'title': '失眠', 'description': '0.无 1.轻度入睡困难 2.中度入睡困难和睡眠不深 3.重度，睡眠持续受扰 4.极重度，睡眠完全丧失'},
    {'num': 5, 'title': '认知功能', 'description': '0.无 1.轻度，注意力涣散 2.中度，明显注意不集中和记忆力差 3.重度，记忆力缺损明显 4.极重度，严重记忆力缺损，定向力丧失'},
    {'num': 6, 'title': '抑郁心境', 'description': '0.无 1.轻度 2.中度，有时出现抑郁 3.重度，经常抑郁 4.极重度，抑郁严重影响生活'},
    {'num': 7, 'title': '躯体性肌肉系统症状', 'description': '0.无 1.轻度 2.中度，不只一种症状且症状明确 3.重度，不只一种症状且症状严重 4.极重度，症状持续大部分时间'},
    {'num': 8, 'title': '躯体性感觉系统症状', 'description': '0.无 1.轻度 2.中度，症状明确 3.重度，症状严重且频繁 4.极重度，症状严重且持续'},
    {'num': 9, 'title': '心血管系统症状', 'description': '0.无 1.轻度 2.中度，症状明确 3.重度，症状严重且频繁 4.极重度，症状严重且持续'},
    {'num': 10, 'title': '呼吸系统症状', 'description': '0.无 1.轻度 2.中度，症状明确 3.重度，症状严重 4.极重度，症状严重且持续'},
    {'num': 11, 'title': '胃肠道症状', 'description': '0.无 1.轻度 2.中度，不只一种症状 3.重度，不只一种症状且严重 4.极重度，症状严重且频繁'},
    {'num': 12, 'title': '泌尿生殖系统症状', 'description': '0.无 1.轻度 2.中度，症状明确 3.重度，症状严重 4.极重度，症状严重且频繁'},
    {'num': 13, 'title': '自主神经系统症状', 'description': '0.无 1.轻度 2.中度，症状明确 3.重度，症状严重 4.极重度，症状严重且频繁'},
    {'num': 14, 'title': '会谈时行为表现', 'description': '0.无 1.轻度 2.中度，表现明显 3.重度，表现严重 4.极重度，惊恐状态'}
]

# YMRS 躁狂量表完整题目
YMRS_QUESTIONS = [
    {'num': 1, 'title': '心境高涨', 'description': '0.无 1.询问时承认有轻度或可能的心境高涨 2.主观感到肯定有心境高涨、乐观自信、愉快 3.与他人交往明显乐观、愉快、过分热情 4.欣喜若狂、经常大笑'},
    {'num': 2, 'title': '精力和活动增加', 'description': '0.无 1.主观上感到精力增加 2.活泼好动、精力旺盛 3.浪费精力在无关或不必要的计划或目标上 4.精力亢盛、活动过度'},
    {'num': 3, 'title': '性兴趣', 'description': '0.正常、无增强 1.轻度或可能增强 2.从患者的言谈中明显地描述性兴趣增强 3.有性方面的不恰当行为 4.公开的性行为'},
    {'num': 4, 'title': '睡眠', 'description': '0.未报告睡眠减少 1.睡眠较平时减少至多2小时 2.睡眠较平时减少多于2小时 3.声称不需要睡眠'},
    {'num': 5, 'title': '易激惹', 'description': '0.无 1.主观上感到易激惹 2.会谈时易激惹或易激怒，近来有易激惹发作史 3.会谈时易激怒，很快恢复，经常易激惹 4.经常有敌意、不合作'},
    {'num': 6, 'title': '语速和语量', 'description': '0.无增多 1.感到比平时健谈 2.健谈、言语增多或说话速度增快 3.经常健谈、难以打断其谈话 4.连续讲话、不能打断、滔滔不绝'},
    {'num': 7, 'title': '语言-思维紊乱', 'description': '0.无 1.环境性、轻度离题、思维较快 2.常有离题、思维奔逸 3.经常很难与之交谈，有明显的语无伦次 4.无法交谈，严重的语无伦次或不连贯'},
    {'num': 8, 'title': '思维内容', 'description': '0.正常 1.有新的兴趣或计划，但未达到夸大程度 2.特殊的计划、夸耀自己的新身份 3.夸大性观念 4.夸大妄想或偏执妄想'},
    {'num': 9, 'title': '攻击-破坏行为', 'description': '0.无、合作 1.讽刺挖苦、言语尖锐、发牢骚 2.提高嗓音、大声争论 3.威胁检查者、大声吼叫 4.攻击性破坏性行为'},
    {'num': 10, 'title': '外表', 'description': '0.衣着得体、梳洗整齐 1.衣着略邋遢 2.衣着不太得体、外观略显凌乱 3.着装古怪、不太得体或奇特 4.穿衣奇装异服、很不修边幅'},
    {'num': 11, 'title': '自知力', 'description': '0.承认有病，同意需要治疗 1.可能有病，可能需要治疗 2.承认行为改变，但否认有病 3.否认有任何行为改变'}
]


class TableStylePDFGenerator:
    """三列表格样式PDF生成器"""
    
    def __init__(self):
        try:
            # 尝试加载中文字体
            font_path = 'C:/Windows/Fonts/simhei.ttf'
            if os.path.exists(font_path):
                pdfmetrics.registerFont(TTFont('SimHei', font_path))
                self.font_name = 'SimHei'
            else:
                # 尝试其他字体
                font_path = 'C:/Windows/Fonts/simsun.ttc'
                if os.path.exists(font_path):
                    pdfmetrics.registerFont(TTFont('SimSun', font_path))
                    self.font_name = 'SimSun'
                else:
                    self.font_name = 'Helvetica'
        except Exception as e:
            print(f"字体加载失败: {e}")
            self.font_name = 'Helvetica'
    
    def generate_patient_report(self, patient_info, assessment_data, output_path):
        """生成患者评估报告PDF"""
        doc = SimpleDocTemplate(
            output_path,
            pagesize=A4,
            rightMargin=1.5*cm,
            leftMargin=1.5*cm,
            topMargin=1.5*cm,
            bottomMargin=1.5*cm
        )
        
        story = []
        styles = self._create_styles()
        
        # 1. 标题
        story.append(Paragraph('患者评估详细报告', styles['ReportTitle']))
        story.append(Spacer(1, 0.5*cm))
        
        # 2. 患者信息
        story.extend(self._create_patient_info_card(patient_info, assessment_data, styles))
        story.append(Spacer(1, 0.8*cm))
        
        # 3. HAMD量表
        if assessment_data.get('hamd_status') == 1 and assessment_data.get('hamd_details'):
            story.extend(self._create_scale_table('hamd', assessment_data, styles))
            story.append(PageBreak())
        
        # 4. HAMA量表
        if assessment_data.get('hama_status') == 1 and assessment_data.get('hama_details'):
            story.extend(self._create_scale_table('hama', assessment_data, styles))
            story.append(PageBreak())
        
        # 5. YMRS量表
        if assessment_data.get('ymrs_status') == 1 and assessment_data.get('ymrs_details'):
            story.extend(self._create_scale_table('ymrs', assessment_data, styles))
        
        # 6. 页脚
        story.append(Spacer(1, 0.5*cm))
        story.append(Paragraph(
            f'报告生成时间：{datetime.datetime.now().strftime("%Y年%m月%d日 %H:%M")}',
            styles['ReportFooter']
        ))
        
        doc.build(story)
        return output_path
    
    def _create_styles(self):
        """创建样式"""
        styles = getSampleStyleSheet()
        
        # 使用自定义名称避免与默认样式冲突
        styles.add(ParagraphStyle(
            name='ReportTitle',
            fontName=self.font_name,
            fontSize=18,
            leading=24,
            alignment=TA_CENTER,
            textColor=colors.HexColor('#333333'),
            spaceAfter=10
        ))
        
        styles.add(ParagraphStyle(
            name='ScaleTitle',
            fontName=self.font_name,
            fontSize=14,
            leading=18,
            textColor=colors.HexColor('#333333'),
            spaceAfter=8,
            spaceBefore=5
        ))
        
        styles.add(ParagraphStyle(
            name='ReportFooter',
            fontName=self.font_name,
            fontSize=9,
            textColor=colors.HexColor('#999999'),
            alignment=TA_CENTER
        ))
        
        return styles
    
    def _create_patient_info_card(self, patient_info, assessment_data, styles):
        """创建患者信息卡片"""
        content = []
        
        # 患者信息表格
        info_data = [
            ['患者姓名', patient_info.get('real_name', '未知'), '性别', '男' if patient_info.get('gender') == 1 else '女'],
            ['年龄', f"{patient_info.get('age', '未知')}岁", '联系电话', patient_info.get('phone', '未提供')],
            ['评估日期', assessment_data.get('assessment_date', ''), '评估类型', assessment_data.get('assessment_type_name', '')]
        ]
        
        # 如果有评估者信息
        if assessment_data.get('assessor_name'):
            info_data.append([
                '评估者', assessment_data.get('assessor_name', ''), '评估时间', assessment_data.get('create_time', '')
            ])
        
        info_table = Table(info_data, colWidths=[3*cm, 5.5*cm, 3*cm, 5.5*cm])
        info_table.setStyle(TableStyle([
            ('FONTNAME', (0, 0), (-1, -1), self.font_name),
            ('FONTSIZE', (0, 0), (-1, -1), 11),
            ('BACKGROUND', (0, 0), (0, -1), colors.HexColor('#E8F4F8')),
            ('BACKGROUND', (2, 0), (2, -1), colors.HexColor('#E8F4F8')),
            ('TEXTCOLOR', (0, 0), (-1, -1), colors.HexColor('#333333')),
            ('ALIGN', (0, 0), (-1, -1), 'LEFT'),
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
            ('GRID', (0, 0), (-1, -1), 1, colors.HexColor('#CCCCCC')),
            ('LEFTPADDING', (0, 0), (-1, -1), 10),
            ('RIGHTPADDING', (0, 0), (-1, -1), 10),
            ('TOPPADDING', (0, 0), (-1, -1), 8),
            ('BOTTOMPADDING', (0, 0), (-1, -1), 8),
        ]))
        
        content.append(info_table)
        content.append(Spacer(1, 0.3*cm))
        
        # 评估结果摘要
        summary_data = [['量表名称', '总分', '严重程度']]
        has_any_scale = False
        
        if assessment_data.get('hamd_status') == 1:
            has_any_scale = True
            summary_data.append([
                'HAMD-17（抑郁量表）',
                f"{assessment_data.get('hamd_total', 0)}分",
                self._get_severity('hamd', assessment_data.get('hamd_total', 0))
            ])
        
        if assessment_data.get('hama_status') == 1:
            has_any_scale = True
            summary_data.append([
                'HAMA-14（焦虑量表）',
                f"{assessment_data.get('hama_total', 0)}分",
                self._get_severity('hama', assessment_data.get('hama_total', 0))
            ])
        
        if assessment_data.get('ymrs_status') == 1:
            has_any_scale = True
            summary_data.append([
                'YMRS（躁狂量表）',
                f"{assessment_data.get('ymrs_total', 0)}分",
                self._get_severity('ymrs', assessment_data.get('ymrs_total', 0))
            ])
        
        if has_any_scale:
            summary_table = Table(summary_data, colWidths=[7*cm, 5*cm, 5.5*cm])
            summary_table.setStyle(TableStyle([
                ('FONTNAME', (0, 0), (-1, -1), self.font_name),
                ('FONTSIZE', (0, 0), (-1, -1), 11),
                ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#4A90E2')),
                ('TEXTCOLOR', (0, 0), (-1, 0), colors.white),
                ('FONTSIZE', (0, 0), (-1, 0), 12),
                ('TEXTCOLOR', (0, 1), (-1, -1), colors.HexColor('#333333')),
                ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
                ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
                ('GRID', (0, 0), (-1, -1), 1, colors.HexColor('#CCCCCC')),
                ('TOPPADDING', (0, 0), (-1, -1), 8),
                ('BOTTOMPADDING', (0, 0), (-1, -1), 8),
                ('ROWBACKGROUNDS', (0, 1), (-1, -1), [colors.white, colors.HexColor('#F9F9F9')])
            ]))
            content.append(summary_table)
        
        return content
    
    def _parse_score_description(self, full_description, score):
        """从完整描述中提取指定分数对应的描述"""
        parts = re.split(r'(\d+\.)', full_description)
        score_dict = {}
        
        for i in range(1, len(parts), 2):
            if i+1 < len(parts):
                score_num = int(parts[i].replace('.', ''))
                description = parts[i+1].strip()
                score_dict[score_num] = f"{score_num}.{description}"
        
        result = score_dict.get(score, f"{score}分")
        
        # 截断过长的描述
        if len(result) > 50:
            for delimiter in ['，', '、', '；']:
                if delimiter in result:
                    result = result.split(delimiter)[0] + delimiter
                    break
            if len(result) > 50:
                result = result[:47] + "..."
        
        return result
    
    def _create_scale_table(self, scale_type, assessment_data, styles):
        """创建量表表格"""
        content = []
        
        scale_names = {
            'hamd': '汉密尔顿抑郁量表（HAMD-17）',
            'hama': '汉密尔顿焦虑量表（HAMA-14）',
            'ymrs': '杨氏躁狂评定量表（YMRS）'
        }
        
        content.append(Paragraph(scale_names[scale_type], styles['ScaleTitle']))
        content.append(Spacer(1, 0.3*cm))
        
        # 获取题目和分数
        if scale_type == 'hamd':
            questions = HAMD_QUESTIONS
            scores = assessment_data.get('hamd_details', [])
            total_score = assessment_data.get('hamd_total', 0)
        elif scale_type == 'hama':
            questions = HAMA_QUESTIONS
            scores = assessment_data.get('hama_details', [])
            total_score = assessment_data.get('hama_total', 0)
        else:  # ymrs
            questions = YMRS_QUESTIONS
            scores = assessment_data.get('ymrs_details', [])
            total_score = assessment_data.get('ymrs_total', 0)
        
        # 创建单元格样式（用于自动换行）
        cell_style = ParagraphStyle(
            name='CellText',
            fontName=self.font_name,
            fontSize=9,
            leading=12,
            wordWrap='CJK'
        )
        
        # 构建表格数据
        table_data = [['项目', '题目', '结果']]
        
        for idx, question in enumerate(questions):
            score = scores[idx] if idx < len(scores) else 0
            
            item_text = f"{question['num']}. {question['title']}"
            desc_text = question['description']
            result_text = self._parse_score_description(question['description'], score)
            
            # 将长文本包装成Paragraph以支持自动换行
            table_data.append([
                Paragraph(item_text, cell_style),
                Paragraph(desc_text, cell_style),
                Paragraph(result_text, cell_style)
            ])
        
        # 创建表格
        table = Table(table_data, colWidths=[3.5*cm, 10*cm, 4*cm])
        
        table.setStyle(TableStyle([
            ('FONTNAME', (0, 0), (-1, -1), self.font_name),
            ('FONTSIZE', (0, 0), (-1, -1), 9),
            ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#4A90E2')),
            ('TEXTCOLOR', (0, 0), (-1, 0), colors.white),
            ('FONTSIZE', (0, 0), (-1, 0), 10),
            ('ALIGN', (0, 0), (-1, 0), 'CENTER'),
            ('TEXTCOLOR', (0, 1), (-1, -1), colors.HexColor('#333333')),
            ('ALIGN', (0, 1), (0, -1), 'LEFT'),
            ('ALIGN', (1, 1), (1, -1), 'LEFT'),
            ('ALIGN', (2, 1), (2, -1), 'LEFT'),
            ('VALIGN', (0, 0), (-1, 0), 'MIDDLE'),  # 表头居中
            ('VALIGN', (0, 1), (-1, -1), 'TOP'),    # 内容行顶部对齐，更适合多行文本
            ('GRID', (0, 0), (-1, -1), 0.5, colors.HexColor('#CCCCCC')),
            ('LEFTPADDING', (0, 0), (-1, -1), 8),
            ('RIGHTPADDING', (0, 0), (-1, -1), 8),
            ('TOPPADDING', (0, 0), (-1, -1), 8),
            ('BOTTOMPADDING', (0, 0), (-1, -1), 8),
            ('ROWBACKGROUNDS', (0, 1), (-1, -1), [colors.white, colors.HexColor('#F9F9F9')])
        ]))
        
        content.append(table)
        
        # 总分
        content.append(Spacer(1, 0.5*cm))
        severity = self._get_severity(scale_type, total_score)
        total_text = f"<b>{scale_names[scale_type]} 总分：{total_score}分  —  {severity}</b>"
        content.append(Paragraph(total_text, styles['ScaleTitle']))
        
        return content
    
    def _get_severity(self, scale_type, score):
        """获取严重程度"""
        if scale_type == 'hamd':
            if score < 7: return '正常'
            if score < 17: return '轻度抑郁'
            if score < 24: return '中度抑郁'
            return '重度抑郁'
        elif scale_type == 'hama':
            if score < 7: return '正常'
            if score < 14: return '轻度焦虑'
            if score < 21: return '中度焦虑'
            return '重度焦虑'
        elif scale_type == 'ymrs':
            if score < 5: return '正常'
            if score < 15: return '轻度躁狂'
            if score < 25: return '中度躁狂'
            return '重度躁狂'
        return '未知'

